home *** CD-ROM | disk | FTP | other *** search
- /* utils.cpp / text and pointer manipulation utilities for error reporter */
-
- #include <stdio.h>
- #include <ctype.h> /* isalpha() etc. */
- #include <string.h> /* strncpy() etc. */
- #include <stdlib.h>
- #include "utils.hpp"
-
- int skipblanks(const char *s)
- {
- /* skip leading white space and return a count of characters skipped. */
-
- const char *start = s;
-
- while (*s && isspace(*s))
- ++s;
- return s - start;
-
- } /* end of skipblanks() */
-
- int skip_ident(const char *s)
- {
- /* skip leading alphanumeric characters (a-zA-Z0-9_) and return a */
- /* count of characters skipped. */
-
- const char *start = s;
-
- while (*s && (isalpha(*s) || isdigit(*s) || *s == '_'))
- ++s;
- return s - start;
-
- } /* end of skip_ident() */
-
- char *newstring(const char *s,int len)
- {
- /* allocate storage for some text. if the length is specified we */
- /* use that; otherwise we use strlen(s). */
-
- char *new_s;
-
- if (s == 0)
- return 0;
- if (len == 0) /* default: find length of string */
- len = strlen(s);
- new_s = (char *) malloc(len + 1); /* allocate space for '\0' too */
- strncpy(new_s,s,len);
- new_s[len] = '\0'; /* in case strncpy() didn't */
- return new_s;
-
- } /* end of newstring() */
-
- void read_continued_line(FILE *f,char *line,int linelen)
- {
- /* read a complaint file line, merging continuation lines together. */
-
- size_t thislen,lastlen;
-
- line[0] = '\0'; /* clear old data */
- fgets(line,linelen,f); /* get first line of text */
- thislen = strlen(line);
- if (thislen == 0) /* EOF? done */
- return;
-
- /* add continuation lines, each terminated by '\\'. effectively we */
- /* quote the trailing newline. */
-
- lastlen = 0;
- while (thislen != lastlen && thislen > 1 &&
- line[thislen - 1] == '\n' &&
- line[thislen - 2] == '\\') {
- line[thislen - 2] = '\n'; /* remove '\\', '\n', */
- line[thislen - 1] = '\0'; /* restore '\n' */
- lastlen = thislen - 1;
- if (fgets(line + lastlen,linelen - lastlen,f) == 0) /* next line */
- line[lastlen] = '\0'; /* keep it valid */
- thislen = strlen(line);
- } /* end of while() */
-
- } /* end of read_continued_line() */
-
- /***************************** class ptr_stack *****************************/
-
- const long INITSIZE = 32L;
- const long MAXSIZE = 1024L; /* when we stop doubling size */
-
- ptr_stack::ptr_stack(void)
- {
- top_idx = -1L; /* where top elem is - pre-increment */
- size = INITSIZE;
- elems = (void **) malloc(size * sizeof(void *));
-
- } /* end of ptr_stack::ptr_stack() */
-
- ptr_stack::ptr_stack(const ptr_stack &other) /* copy constructor */
- {
- /* since we don't delete the elements stored in the stack when the */
- /* stack is deleted, nothing special must be done except to copy the */
- /* array holding them. */
-
- int i;
-
- size = other.size;
- elems = (void **) malloc(size * sizeof(void *));
- for (i = 0; i < size; ++i)
- elems[i] = other.elems[i];
- top_idx = other.top_idx;
-
- } /* end of ptr_stack::ptr_stack(ptr_stack &) */
-
- ptr_stack &ptr_stack::operator =(const ptr_stack &other) /* assignment */
- {
- /* we delete everything currently in this stack and copy over the */
- /* things in the other stack. */
-
- int i;
-
- if (this != &other) { /* guard against self-assignment */
- free(elems);
-
- /* this is from the copy constructor; it's not worth the overhead of */
- /* an init() function. */
-
- size = other.size;
- elems = (void **) malloc(size * sizeof(void *));
- for (i = 0; i < size; ++i)
- elems[i] = other.elems[i];
- top_idx = other.top_idx;
- }
- return *this;
-
- } /* end of ptr_stack::operator =() */
-
- ptr_stack::~ptr_stack(void)
- {
- /* clean up the mess. */
-
- free(elems);
-
- } /* end of ptr_stack::~ptr_stack() */
-
- void *ptr_stack::push(void *op)
- {
- /* push the element onto the stack (no type checking). expand the stack */
- /* to prevent overflow, doubling the size until we reach MAXSIZE. */
- /* afterwards, increase the size only by MAXSIZE. */
-
- long i,newsize;
- void **newary;
- /* pre-increment */
- if (++top_idx >= size) { /* expand on overflow */
- newsize = size + ((size >= MAXSIZE) ? MAXSIZE : size);
- newary = (void **) malloc(newsize * sizeof(void *));
- for (i = 0L; i < size; ++i)
- newary[i] = elems[i];
- free(elems);
- elems = newary;
- size = newsize;
- }
- elems[top_idx] = op;
- return op;
-
- } /* end of ptr_stack::push() */
-
- void *ptr_stack::pop(void)
- {
- /* remove the top element from the stack and return it. */
-
- if (top_idx < 0L)
- return 0;
- return elems[top_idx--]; /* post-decrement */
-
- } /* end of ptr_stack::pop() */
-
- void *ptr_stack::top(void) const
- {
- /* return the top element of the stack without removing it. */
-
- if (top_idx < 0L)
- return 0;
- return elems[top_idx]; /* leave top_idx alone! */
-
- } /* end of ptr_stack::top() */
-
- long ptr_stack::elem_count(void)
- {
- /* how many elements have been pushed onto the stack? */
-
- return top_idx + 1L;
-
- } /* end of ptr_stack::elem_count() */